package com.tanhua.server.service;

import com.tanhua.commons.exception.TanHuaException;
import com.tanhua.commons.templates.OssTemplate;
import com.tanhua.domain.mongo.Comment;
import com.tanhua.domain.db.UserInfo;
import com.tanhua.domain.mongo.Publish;
import com.tanhua.domain.mongo.Visitor;
import com.tanhua.domain.vo.*;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.mongo.CommentApi;
import com.tanhua.dubbo.api.mongo.PublishApi;
import com.tanhua.dubbo.api.mongo.VisitorApi;
import com.tanhua.server.interceptor.UserHolder;
import com.tanhua.server.utils.RelativeDateFormat;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.bson.types.ObjectId;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 圈子-业务层处理
 */
@Service
public class MovementsService {

    @Reference
    private PublishApi publishApi;

    @Autowired
    private OssTemplate ossTemplate;

    @Reference
    private UserInfoApi userInfoApi;


    @Reference
    private CommentApi commentApi;

    @Reference
    private VisitorApi visitorApi;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 发布动态
     */
    public void movements(PublishVo publishVo, MultipartFile[] imageContent) {
        //1.将请求的参数处理调用服务提供者
        try {
            publishVo.setUserId(UserHolder.getUserId());//当前登录用户id
            List<String> medias = new ArrayList<>();
            if (imageContent != null && imageContent.length > 0) {
                for (MultipartFile multipartFile : imageContent) {
                    //原始文件名称
                    String originalFilename = multipartFile.getOriginalFilename();
                    //图片上传
                    String urlFileName = ossTemplate.upload(originalFilename, multipartFile.getInputStream());
                    medias.add(urlFileName);
                }
            }
            publishVo.setMedias(medias);//图片url地址
            publishApi.save(publishVo);
        } catch (IOException e) {
            throw new TanHuaException(ErrorResult.uploadPicFail());
        }
    }

    /**
     * 查询好友动态
     */
    public PageResult<MomentVo> queryMovements(int page, int pagesize) {
        //当前登录用户id
        Long userId = UserHolder.getUserId();
        PageResult<MomentVo> pageResult = new PageResult<>();
        //1.当前登录用户id（作为时间线表表名其中一部分quanzi_time_line_1） 、page 、pagesize
        PageResult<Publish> publishPageResult = publishApi.queryMovements(userId, page, pagesize);
        //2.循环遍历 根据好友id  查询好友信息
        //定义
        List<MomentVo> momentVoList = new ArrayList<>();
        if (publishPageResult != null) {
            List<Publish> items = publishPageResult.getItems();
            if (items != null && items.size() > 0) {
                for (Publish publish : items) {
                    MomentVo momentVo = new MomentVo();
                    Long friendUserId = publish.getUserId();//好友id
                    UserInfo userInfo = userInfoApi.findByUserId(friendUserId);
                    BeanUtils.copyProperties(userInfo, momentVo);
                    BeanUtils.copyProperties(publish, momentVo);
                    momentVo.setImageContent(publish.getMedias().toArray(new String[]{}));//图片列表
                    momentVo.setDistance("10米");
                    momentVo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));
                    momentVo.setTags(userInfo.getTags().split(","));//标签
                    momentVo.setUserId(friendUserId);//好友id
                    momentVo.setId(publish.getId().toHexString());//动态id
                    String likeKey = "publish_like_" + userId + "_" + publish.getId().toHexString();
                    String loveKey = "publish_love_" + userId + "_" + publish.getId().toHexString();
                    if (redisTemplate.hasKey(likeKey)) {
                        momentVo.setHasLiked(1);//是否点赞
                    } else {
                        momentVo.setHasLiked(0);//是否点赞
                    }
                    if (redisTemplate.hasKey(loveKey)) {
                        momentVo.setHasLoved(1);//是否喜欢
                    } else {
                        momentVo.setHasLoved(0);//是否喜欢
                    }
                    momentVoList.add(momentVo);
                }
            }
        }
        //3.构造VO
        BeanUtils.copyProperties(publishPageResult, pageResult);
        pageResult.setItems(momentVoList);
        return pageResult;
    }


    /**
     * 查询推荐动态
     */
    public PageResult<MomentVo> queryRecommend(int page, int pagesize) {
        //当前登录用户id
        Long userId = UserHolder.getUserId();
        PageResult<MomentVo> pageResult = new PageResult<>();
        //1.当前登录用户id（作为时间线表表名其中一部分quanzi_time_line_1） 、page 、pagesize
        PageResult<Publish> publishPageResult = publishApi.queryRecommend(userId, page, pagesize);
        //2.循环遍历 根据好友id  查询好友信息
        //定义
        List<MomentVo> momentVoList = new ArrayList<>();
        if (publishPageResult != null) {
            List<Publish> items = publishPageResult.getItems();
            if (items != null && items.size() > 0) {
                for (Publish publish : items) {
                    MomentVo momentVo = new MomentVo();
                    Long friendUserId = publish.getUserId();//好友id
                    UserInfo userInfo = userInfoApi.findByUserId(friendUserId);
                    BeanUtils.copyProperties(userInfo, momentVo);
                    BeanUtils.copyProperties(publish, momentVo);
                    momentVo.setImageContent(publish.getMedias().toArray(new String[]{}));//图片列表
                    momentVo.setDistance("10米");
                    momentVo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));
                    momentVo.setTags(userInfo.getTags().split(","));//标签
                    momentVo.setUserId(friendUserId);//好友id
                    momentVo.setId(publish.getId().toHexString());//动态id
                    String likeKey = "publish_like_" + userId + "_" + publish.getId().toHexString();
                    String loveKey = "publish_love_" + userId + "_" + publish.getId().toHexString();
                    if (redisTemplate.hasKey(likeKey)) {
                        momentVo.setHasLiked(1);//是否点赞
                    } else {
                        momentVo.setHasLiked(0);//是否点赞
                    }
                    if (redisTemplate.hasKey(loveKey)) {
                        momentVo.setHasLoved(1);//是否喜欢
                    } else {
                        momentVo.setHasLoved(0);//是否喜欢
                    }
                    momentVo.setHasLoved(0);//是否喜欢
                    momentVoList.add(momentVo);
                }
            }
        }
        //3.构造VO
        BeanUtils.copyProperties(publishPageResult, pageResult);
        pageResult.setItems(momentVoList);
        return pageResult;
    }

    /**
     * 我的动态
     */
    public PageResult<MomentVo> queryMyAlbum(int page, int pagesize, Long userId) {
        PageResult<MomentVo> pageResult = new PageResult<>();
        //a.调用mongodb查询我的动态列表PageResult<Publish>
        PageResult<Publish> publishPageResult = publishApi.queryMyAlbum(userId, page, pagesize);
        //b.根据当前用户id查询userInfo
        //定义
        List<MomentVo> momentVoList = new ArrayList<>();
        if (publishPageResult == null) {
            return null;
        }
        List<Publish> items = publishPageResult.getItems();
        if (items == null || items.size() == 0) {
            return null;
        }
        for (Publish publish : items) {
            MomentVo momentVo = new MomentVo();
            UserInfo userInfo = userInfoApi.findByUserId(userId);
            BeanUtils.copyProperties(userInfo, momentVo);
            BeanUtils.copyProperties(publish, momentVo);
            momentVo.setImageContent(publish.getMedias().toArray(new String[]{}));//图片列表
            //momentVo.setDistance("10米");
            momentVo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));
            momentVo.setTags(userInfo.getTags().split(","));//标签
            momentVo.setUserId(userId);//当前登录用户id
            momentVo.setId(publish.getId().toHexString());//动态id
            String likeKey = "publish_like_" + userId + "_" + publish.getId().toHexString();
            String loveKey = "publish_love_" + userId + "_" + publish.getId().toHexString();
            if (redisTemplate.hasKey(likeKey)) {
                momentVo.setHasLiked(1);//是否点赞
            } else {
                momentVo.setHasLiked(0);//是否点赞
            }
            if (redisTemplate.hasKey(loveKey)) {
                momentVo.setHasLoved(1);//是否喜欢
            } else {
                momentVo.setHasLoved(0);//是否喜欢
            }
            momentVoList.add(momentVo);
        }
        //c.封装VO返回
        BeanUtils.copyProperties(publishPageResult, pageResult);
        pageResult.setItems(momentVoList);
        return pageResult;
    }

    /**
     * 动态点赞
     */
    public Long like(String publishId) {
        Long userId = UserHolder.getUserId();//当前登录用户id
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(publishId));//发布id
        comment.setCommentType(1); //评论类型，1-点赞，2-评论，3-喜欢
        comment.setPubType(1);//评论内容类型： 1-对动态操作 2-对视频操作 3-对评论操作
        comment.setUserId(userId);//当前登录用户id
        //a.获取当前用户id 发布表动态id 保存评论记录（点赞记录）返回点赞数量
        Long total = commentApi.save(comment);//保存点赞记录
        //d.将点赞记录写入redis  key=commentType+userId+publishId  value=任意值
        String key = "publish_like_" + userId + "_" + publishId;
        redisTemplate.opsForValue().set(key, "true");
        return total;
    }

    /**
     * 动态取消点赞
     */
    public Long dislike(String publishId) {
        Long userId = UserHolder.getUserId();//当前登录用户id
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(publishId));//发布id
        comment.setCommentType(1); //评论类型，1-点赞，2-评论，3-喜欢
        comment.setPubType(1);//评论内容类型： 1-对动态操作 2-对视频操作 3-对评论操作
        comment.setUserId(userId);//当前登录用户id
        //a.获取当前用户id 发布表动态id 保存评论记录（点赞记录）返回点赞数量
        Long total = commentApi.remove(comment);//保存点赞记录
        //d.将点赞记录写入redis
        String key = "publish_like_" + userId + "_" + publishId;
        redisTemplate.delete(key);
        return total;
    }

    /**
     * 动态喜欢
     */
    public Long love(String publishId) {
        Long userId = UserHolder.getUserId();//当前登录用户id
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(publishId));//发布id
        comment.setCommentType(3); //评论类型，1-点赞，2-评论，3-喜欢
        comment.setPubType(1);//评论内容类型： 1-对动态操作 2-对视频操作 3-对评论操作
        comment.setUserId(userId);//当前登录用户id
        //a.获取当前用户id 发布表动态id 保存评论记录（点赞记录）返回点赞数量
        Long total = commentApi.save(comment);//保存点赞记录
        //d.将点赞记录写入redis  key=commentType+userId+publishId  value=任意值
        String key = "publish_love_" + userId + "_" + publishId;
        redisTemplate.opsForValue().set(key, "true");
        return total;
    }

    /**
     * 动态取消喜欢
     */
    public Long unlove(String publishId) {
        Long userId = UserHolder.getUserId();//当前登录用户id
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(publishId));//发布id
        comment.setCommentType(3); //评论类型，1-点赞，2-评论，3-喜欢
        comment.setPubType(1);//评论内容类型： 1-对动态操作 2-对视频操作 3-对评论操作
        comment.setUserId(userId);//当前登录用户id
        //a.获取当前用户id 发布表动态id 保存评论记录（点赞记录）返回点赞数量
        Long total = commentApi.remove(comment);//保存点赞记录
        //d.将点赞记录写入redis
        String key = "publish_love_" + userId + "_" + publishId;
        redisTemplate.delete(key);
        return total;
    }

    /**
     * 查询单条动态
     */
    public MomentVo queryById(String publishId) {

        //当前登录用户id
        Long userId = UserHolder.getUserId();
        //1.根据发布id查询发布信息（动态）
        Publish publish = publishApi.queryById(publishId);
        if (publish == null) {
            return null;
        }
        //2.将publish 转为 MomentVo
        MomentVo momentVo = new MomentVo();
        Long friendUserId = publish.getUserId();//好友id
        UserInfo userInfo = userInfoApi.findByUserId(friendUserId);
        BeanUtils.copyProperties(userInfo, momentVo);
        BeanUtils.copyProperties(publish, momentVo);
        momentVo.setImageContent(publish.getMedias().toArray(new String[]{}));//图片列表
        momentVo.setDistance("10米");
        momentVo.setCreateDate(RelativeDateFormat.format(new Date(publish.getCreated())));
        momentVo.setTags(userInfo.getTags().split(","));//标签
        momentVo.setId(publish.getId().toHexString());//动态id
        String likeKey = "publish_like_" + userId + "_" + publish.getId().toHexString();
        String loveKey = "publish_love_" + userId + "_" + publish.getId().toHexString();
        if (redisTemplate.hasKey(likeKey)) {
            momentVo.setHasLiked(1);//是否点赞
        } else {
            momentVo.setHasLiked(0);//是否点赞
        }
        if (redisTemplate.hasKey(loveKey)) {
            momentVo.setHasLoved(1);//是否喜欢
        } else {
            momentVo.setHasLoved(0);//是否喜欢
        }
        momentVo.setHasLoved(0);//是否喜欢
        return momentVo;
    }

    /**
     * 谁看过我
     */
    public List<VisitorVo> lookeMe() {
        Long userId = UserHolder.getUserId();//当前登录用户id
        String key = "visitor_" + userId;
        //a.查询redis是否存在上次访问时间，如果有，查询date>redis上次访问时间 limit 5
        String time = redisTemplate.opsForValue().get(key);
        List<Visitor> visitorList = null;
        if (StringUtils.isNotEmpty(time)) {
            visitorList = visitorApi.queryVisitors(time, userId);
        } else {
            //b.如果没有，查询visitors   limit 5
            visitorList = visitorApi.queryVisitors(userId);
        }

        List<VisitorVo> visitorVoList = new ArrayList<>();
        if(visitorList == null || visitorList.size() ==0){
            return null;
        }
        for (Visitor visitor : visitorList) {
            VisitorVo visitorVo = new VisitorVo();
            //c.查询userInfo
            Long visitorUserId = visitor.getVisitorUserId();//访客用户id
            UserInfo userInfo = userInfoApi.findByUserId(visitorUserId);
            BeanUtils.copyProperties(userInfo,visitorVo);
            visitorVo.setTags(userInfo.getTags().split(","));
            visitorVo.setFateValue(80);//写死
            visitorVoList.add(visitorVo);
        }
        ///d.将本次访问时间写入redis
        redisTemplate.opsForValue().set(key,System.currentTimeMillis()+"");
        return visitorVoList;
    }
}
